<?php
// +-------------------------------------------------------------+
// | Tinysupe [ SIMPLE IS THE BEST ! ]
// +-------------------------------------------------------------+
// | Copyright (c) 2012 www.srccn.com All rights reserved.
// +-------------------------------------------------------------+
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +-------------------------------------------------------------+
// | Author: tinysu <tinysu@qq.com>
// +-------------------------------------------------------------+

function whois_ip2long($ipaddr) {
	$iplong = ip2long($ipaddr);
	if ($iplong == -1 || $iplong === false) return false;
	$ip_arr = array_map('intval', split('.', $ipaddr));
	$iplong = (16777216 * $ip_arr[0]) + (65536 * $ip_arr[1]) + (256 * $ip_arr[2]) + $ip_arr[3];
	return $iplong;
}

function whois_long2ip($iplong) {
	return long2ip($iplong);
}

function whois_ipaddr($ipaddr) {
	$iplong = ip2long($ipaddr);
	if ($iplong == -1 || $iplong === false) return '0.0.0.0';
	return implode('.', array_map('intval', explode('.', $ipaddr)));
}

function whois_domain($domain) {
	// idns lists
	$idns = array(
		'ac', 'aero', 'asia', 'biz', 'com', 'coop', 'edu',
		'gov', 'info', 'name', 'net', 'org', 'pro'
	);
	// tlds lists
	$tlds = array(
		'ad', 'ae', 'ag', 'ai', 'al', 'an', 'ao', 'aq', 'ar',
		'as', 'am', 'au', 'at', 'az', 'ba', 'bb', 'be', 'bf',
		'bg', 'bh', 'bi', 'bm', 'bn', 'bo', 'by', 'bz', 'br',
		'bt', 'bv', 'ca', 'cc', 'cd', 'cf', 'cg', 'ch', 'ci',
		'ck', 'cl', 'cm', 'cn', 'co', 'cu', 'cx', 'cy', 'cz',
		'de', 'dk', 'dj', 'do', 'dz', 'ec', 'ee', 'eg', 'es',
		'et', 'fi', 'fj', 'fk', 'fm', 'fo', 'fr', 'gb', 'ge',
		'gf', 'gg', 'gh', 'gi', 'gl', 'gm', 'gn', 'gp', 'gq',
		'gr', 'gs', 'gt', 'gu', 'hk', 'hm', 'hn', 'hr', 'hu',
		'id', 'ie', 'il', 'im', 'in', 'int', 'io', 'ir', 'is',
		'it', 'je', 'jo', 'jp', 'ke', 'kg', 'kh', 'kn', 'kr',
		'kw', 'kz', 'la', 'lb', 'lc', 'li', 'lk', 'lr', 'ls',
		'lt', 'lu', 'lv', 'ly', 'ma', 'mc', 'md', 'mil', 'mg',
		'mh', 'mk', 'mm', 'mn', 'mo', 'mp', 'mq', 'mr', 'ms',
		'mt', 'mu', 'mw', 'mx', 'my', 'mz', 'na', 'nc', 'nf',
		'ni', 'nl', 'no', 'np', 'nu', 'nz', 'om', 'pa', 'pe',
		'ph', 'pg', 'pk', 'pl', 'pm', 'pn', 'pr', 'ps', 'pt',
		'py', 'qa', 're', 'ro', 'ru', 'rw', 'sa', 'sb', 'sd',
		'se', 'sg', 'sh', 'si', 'sj', 'sk', 'sm', 'sn', 'so',
		'st', 'su', 'sv', 'sz', 'tc', 'td', 'tf', 'tg', 'th',
		'tj', 'tm', 'tn', 'to', 'tp', 'tr', 'tt', 'tw', 'tz',
		'tv', 'ua', 'ug', 'uk', 'uk', 'um', 'us', 'uy', 'uz',
		've', 'wf', 'vg', 'vi', 'vn', 'vu', 'ws', 'yt', 'yu',
		'za', 'zm'
	);
	// sub-tlds lists
	$subs = array();
	// cn
	$subs['cn'] = array(
		'ac', 'aero', 'asia', 'biz', 'com', 'coop', 'edu',
		'gov', 'info', 'name', 'net', 'org', 'pro',
		'bj', 'sh', 'tj', 'cq', 'he', 'sx', 'nm', 'ln', 'jl',
		'hl', 'js', 'zj', 'ah', 'fj', 'jx', 'sd', 'ha', 'hb',
		'hn', 'gd', 'gx', 'hi', 'sc', 'gz', 'yn', 'xz', 'sn',
		'gs', 'qh', 'nx', 'xj', 'tw', 'hk', 'mo'
	);
	// jp
	$subs['jp'] = array(
		'ac', 'aero', 'asia', 'biz', 'com', 'coop', 'edu',
		'gov', 'info', 'name', 'net', 'org', 'pro',
		'co', 'or'
	);
	// kr
	$subs['kr'] = array(
		'ac', 'aero', 'asia', 'biz', 'com', 'coop', 'edu',
		'gov', 'info', 'name', 'net', 'org', 'pro',
		'co', 'or'
	);
	// uk
	$subs['uk'] = array(
		'ac', 'aero', 'asia', 'biz', 'com', 'coop', 'edu',
		'gov', 'info', 'name', 'net', 'org', 'pro',
		'co'
	);
	
	// surfix lists
	$surfix = array();
	foreach($idns as $tld) $surfix[$tld] = 1;
	foreach($tlds as $tld) $surfix[$tld] = 0;

	// fix the domain name
	$domain = strtolower(trim($domain));
	$domain = preg_replace('/^https:\/\//i', '', $domain);
	$domain = preg_replace('/^http:\/\//i', '', $domain);
	$domain = preg_replace('/^www\./i', '', $domain);
	$domain = explode('/', $domain);
	$domain = trim($domain[0]);
	
	// check domain
	if(!preg_match('/^(?:[\d\w]+(?:-*[\d\w]+)*\.)+\w{2,4}$/', $domain)) return false;
	
	// split the TLD from domain name
	$tld = explode('.', $domain);
	$cnt = count($tld)-1;
	if($cnt==0) return false;
	$tld1 = $tld[$cnt];
	$tld2 = $tld[$cnt-1];
	$tld3 = ($cnt-1 > 0) ? $tld[$cnt-2] : false;
	
	// checking the TLDs
	if(!isset($surfix[$tld1])) return false;
	
	if($surfix[$tld1]) return "$tld2.$tld1";
	
	if(isset($subs[$tld1])){
		if(!in_array($tld2, $subs[$tld1])) return "$tld2.$tld1";
	}else{
		if(!in_array($tld2, $idns)) return "$tld2.$tld1";
	}

	if(!empty($tld3)) return "$tld3.$tld2.$tld1";
	
	return "$tld2.$tld1";
}

function whois_array($domain) {
	// whois_array
	$whois = array(
		'domain' => $domain,
		'status' => '',
		'created' => 0,
		'expired' => 0,
		'whoissrv' => '',
		'whoisinfo' => ''
	);
	// whois_query
	if($query = whois_query($domain)){
		// Whois Server
		preg_match('/Domain Name: '.$domain.'\n.*?Whois Server:(.*?)\n/is', $query, $match);
		isset($match[1]) or preg_match('/Sponsoring Registrar:(.*?)\n/is', $query, $match);
		isset($match[1]) or preg_match('/Whois server by(.*?)\n/is', $query, $match);
		$whois['whoissrv'] = isset($match[1]) ? trim($match[1]) : '';
		// Status
		preg_match('/Status:(.*?)\n/is', $query, $match);
		$whois['status'] = isset($match[1]) ? trim($match[1]) : 'Unknown';
		// Creation Date
		preg_match('/Creation Date:(.*?)\n/is', $query, $match);
		isset($match[1]) or preg_match('/Registration Date:(.*?)\n/is', $query, $match);
		isset($match[1]) or preg_match('/Created On:(.*?)\n/is', $query, $match);
		// Korea Registered Date
		isset($match[1]) or preg_match('/Registered Date\s*:(.*?)\n/is', $query, $match);
		$whois['created'] = isset($match[1]) ? trim($match[1]) : 0;
		// Korea Registered Date
		$whois['created'] = preg_replace('/(\d+)\.\s*(\d+)\.\s*(\d+)\./', '$1-$2-$3', $whois['created']);
		$whois['created'] = strtotime($whois['created']) ? strtotime($whois['created']) : 0;
		// Expiration Date
		preg_match('/Expiration Date\s*:(.*?)\n/is', $query, $match);
		$whois['expired'] = isset($match[1]) ? trim($match[1]) : 0;
		// Korea Expiration Date
		$whois['expired'] = preg_replace('/(\d+)\.\s*(\d+)\.\s*(\d+)\./', '$1-$2-$3', $whois['expired']);
		$whois['expired'] = strtotime($whois['expired']) ? strtotime($whois['expired']) : 0;
		
		if($whois['whoissrv'] && whois_domain($whois['whoissrv'])){
			$query .= "\n\n".whois_query($domain, $whois['whoissrv']);
		}
		$whois['whoisinfo'] = $query;
	}
	
	return $whois;
}

function whois_query($domain, $nic_server=null) {
    // fix the domain name:
    $domain = strtolower(trim($domain));
	$domain = preg_replace('/^https:\/\//i', '', $domain);
    $domain = preg_replace('/^http:\/\//i', '', $domain);
    $domain = preg_replace('/^www\./i', '', $domain);
    $domain = explode('/', $domain);
    $domain = trim($domain[0]);
 
    // split the TLD from domain name
    $_domain = explode('.', $domain);
    $lst = count($_domain)-1;
    $ext = $_domain[$lst];
 
    // You find resources and lists 
    // like these on wikipedia: 
    //
    // http://de.wikipedia.org/wiki/Whois
    //
    $servers = array(
        'com'=>'whois.internic.net',   
        'net'=>'whois.internic.net',   
        'org'=>'whois.pir.org',   
        'asia'=>'whois.crsnic.net',  
        'ac'=>'whois.nic.uk',   
        'ad'=>'whois.nic.ad',   
        'ae'=>'whois.uaenic.ae',
        'aero'=>'whois.aero',   
        'ag'=>'whois.nic.ag',   
        'ai'=>'whois.offshore.com.ai',   
        'al'=>'whois.inima.al',   
        'an'=>'whois.una.net',   
        'ao'=>'whois.fccn.pt',   
        'aq'=>'whois.nsrc.org',   
        'ar'=>'whois.nic.ar',   
        'as'=>'whois.nic.as',   
        'am'=>'whois.amnic.net',   
        'au'=>'whois.amnic.net',   
        'at'=>'whois.amnic.net',   
        'az'=>'whois.domain.az',   
        'ba'=>'whois.utic.net.ba',   
        'bb'=>'whois.domains.org.bb',   
        'be'=>'whois.dns.be',   
        'bf'=>'whois.onatel.bf',   
        'bg'=>'whois.digsys.bg',   
        'bh'=>'whois.batelco.com.bh',   
        'bi'=>'whois.nic.bi',   
        'biz'=>'whois.nic.biz',   
        'bm'=>'whois.bermudanic.bm',   
        'bn'=>'whois.brunet.bn',   
        'bo'=>'whois.digsys.bo',   
        'by'=>'whois.unibel.by',   
        'bz'=>'whois.belizenic.bz',   
        'br'=>'whois.registro.fapesp.br',   
        'bt'=>'whois.nic.bt',   
        'bv'=>'whois.norid.no',   
        'ca'=>'whois.cira.ca',   
        'cc'=>'whois.nic.cc',   
        'cd'=>'whois.nic.cd',   
        'cf'=>'whois.socatel.intnet.cf',   
        'cg'=>'whois.nic.cg',   
        'ch'=>'whois.nic.ch',   
        'ci'=>'whois.aipdi.ci',   
        'ck'=>'whois.oyster.net.ck',   
        'cl'=>'whois.nic.cl',   
        'cm'=>'whois.info.intelcam.cm',   
        'cn'=>'whois.cnnic.net.cn',   
        'co'=>'whois.nic.uniandes.edu.co',   
        'coop'=>'whois.nic.coop',   
        'cu'=>'whois.nic.cu',   
        'cx'=>'whois.nic.cx',   
        'cy'=>'whois.nic.cy',   
        'cz'=>'whois.nic.cz',   
        'de'=>'whois.denic.de',   
        'dk'=>'whois.dk-hostmaster.dk',   
        'dj'=>'whois.intnet.dj',   
        'do'=>'whois.nic.do',   
        'dz'=>'whois.nic.dz',   
        'ec'=>'whois.nic.ec',   
        'edu'=>'whois.educause.net',   
        'ee'=>'whois.eenet.ee',   
        'eg'=>'whois.frcu.eun.eg',   
        'es'=>'whois.nic.es',   
        'et'=>'whois.telecom.net.et',   
        'fi'=>'whois.ripe.net',   
        'fj'=>'whois.usp.ac.fj',   
        'fk'=>'whois.fidc.org.fk',   
        'fm'=>'whois.dot.fm',   
        'fo'=>'whois.nic.fo',   
        'fr'=>'whois.nic.fr',   
        'gb'=>'whois.nic.uk',   
        'ge'=>'whois.nic.net.ge',   
        'gf'=>'whois.nplus.gf',   
        'gg'=>'whois.nic.gg',   
        'gh'=>'whois.ghana.com',   
        'gi'=>'whois.gibnet.gi',   
        'gl'=>'whois.nic.gl',   
        'gm'=>'whois.nic.gm',   
        'gn'=>'whois.psg.com',   
        'gov'=>'whois.nic.gov',   
        'gp'=>'whois.nic.gp',   
        'gq'=>'whois.getesa.gq',   
        'gr'=>'whois.hostmaster.gr',   
        'gs'=>'whois.adamsnames.tc',   
        'gt'=>'whois.uvg.edu.gt',   
        'gu'=>'whois.gadao.gov.gu',   
        'hk'=>'whois.hkdnr.net.hk',   
        'hm'=>'whois.registry.hm',   
        'hn'=>'whois.nic.hn',   
        'hr'=>'whois.carnet.hr',   
        'hu'=>'whois.nic.hu',   
        'id'=>'whois.idnet.net.id',   
        'ie'=>'whois.domainregistry.ie',   
        'il'=>'whois.isoc.org.il',   
        'im'=>'whois.nic.im',   
        'in'=>'whois.domain.ncst.ernet.in',   
        'info'=>'whois.afilias.com',   
        'int'=>'whois.iana.org',   
        'io'=>'whois.nic.io',   
        'ir'=>'whois.nic.ir',   
        'is'=>'whois.isnic.is',   
        'it'=>'whois.nic.it',   
        'je'=>'whois.isles.net',   
        'jo'=>'whois.nic.net.jo',   
        'jp'=>'whois.nic.ad.jp',   
        'ke'=>'whois.nbnet.co.ke',   
        'kg'=>'whois.domain.kg',   
        'kh'=>'whois.mptc.gov.kh',   
        'kn'=>'whois.clu.edu',   
        'kr'=>'whois.nic.or.kr',   
        'kw'=>'whois.domainname.net.kw',   
        'kz'=>'whois.domain.kz',
		'la' => 'whois.nic.la',
        'lb'=>'whois.aub.edu.lb',   
        'lc'=>'whois.isisworld.lc',   
        'li'=>'whois.nic.li',   
        'lk'=>'whois.nic.lk',   
        'lr'=>'whois.psg.com',   
        'ls'=>'whois.co.ls',   
        'lt'=>'whois.domreg.lt',   
        'lu'=>'whois.dns.lu',   
        'lv'=>'whois.nic.lv',   
        'ly'=>'whois.nic.ly',   
        'ma'=>'whois.iam.ma',   
        'mc'=>'whois.nic.mc',   
        'md'=>'whois.ripe.net',   
        'mil'=>'whois.nic.mil',   
        'mg'=>'whois.orstom.mg',   
        'mh'=>'whois.nic.net.mh',   
        'mk'=>'whois.mpt.com.mk',   
        'mm'=>'whois.nic.mm',   
        'mn'=>'whois.nic.mn',   
        'mo'=>'whois.umac.mo',   
        'mp'=>'whois.marketplace.mp',   
        'mq'=>'whois.nic.mq',   
        'mr'=>'whois.univ-mkc.mr',   
        'ms'=>'whois.adamsnames.tc',   
        'mt'=>'whois.um.edu.mt',   
        'mu'=>'whois.posix.co.za',   
        'mw'=>'whois.tarsus.net',   
        'mx'=>'whois.nic.mx',   
        'my'=>'whois.mynic.net.my',   
        'mz'=>'whois.nambu.uem.mz',   
        'na'=>'na-nic.com.na',   
        'name'=>'whois.nic.name',   
        'nc'=>'whois.norstom.nc',   
        'nf'=>'whois.names.nf',   
        'ni'=>'whois.nic.ni',   
        'nl'=>'whois.domain-registry.nl',   
        'no'=>'whois.norid.no',   
        'np'=>'whois.mos.com.np',   
        'nu'=>'whois.nic.nu',   
        'nz'=>'whois.domainz.net.nz',   
        'om'=>'whois.gto.net.om',   
        'pa'=>'whois.nic.pa',   
        'pe'=>'whois.ekeko.rcp.net.pe',   
        'ph'=>'whois.domreg.org.ph',   
        'pg'=>'whois.unitech.ac.pg',   
        'pk'=>'whois.pknic.net.pk',   
        'pl'=>'whois.nask.pl',   
        'pm'=>'whois.nic.pm',   
        'pn'=>'whois.nic.pn',   
        'pr'=>'whois.uprr.pr',   
        'pro'=>'whois.registrypro.pro',
        'ps'=>'whois.nic.ps',   
        'pt'=>'whois.fccn.pt',   
        'py'=>'whois.nic.py',   
        'qa'=>'whois.qatar.net.qa',   
        're'=>'whois.nic.fr',   
        'ro'=>'whois.rnc.ro',   
        'ru'=>'whois.ripn.net',   
        'rw'=>'whois.nic.rw',   
        'sa'=>'whois.saudinic.net.sa',   
        'sb'=>'whois.sbnic.net.sb',   
        'sd'=>'whois.sudatel.sd',   
        'se'=>'whois.nic-se.se',   
        'sg'=>'whois.nic.net.sg',   
        'sh'=>'whois.nic.sh',   
        'si'=>'whois.arnes.si',   
        'sj'=>'whois.norid.no',   
        'sk'=>'whois.sk-nic.sk',   
        'sm'=>'whois.intelcom.sm',   
        'sn'=>'whois.nic.sn',   
        'so'=>'whois.nic.so',   
        'st'=>'whois.st-registry.tecnisys.net',   
        'su'=>'whois.ripn.net',   
        'sv'=>'whois.svnet.org.sv',   
        'sz'=>'whois.iafrica.sz',   
        'tc'=>'whois.adamsnames.tc',   
        'td'=>'whois.tit.td',   
        'tf'=>'whois.adamsnames.tc',   
        'tg'=>'whois.nic.tg',   
        'th'=>'whois.thnic.net',   
        'tj'=>'whois.nic.tj',   
        'tm'=>'whois.nic.tm',   
        'tn'=>'whois.ati.tn',   
        'to'=>'whois.tonic.to',   
        'tp'=>'whois.nic.tp',   
        'tr'=>'whois.metu.edu.tr',   
        'tt'=>'whois.nic.tt',   
        'tw'=>'whois.twnic.net',   
        'tz'=>'whois.psg.com',   
        'tv'=>'whois.networksolutions.com',   
        'ua'=>'nic.net.ua',   
        'ug'=>'whois.nic.ug',   
        'uk'=>'whois.nic.uk',   
        'uk'=>'whois.ripe.net',   
        'um'=>'whois.isi.edu',   
        'us'=>'whois.nic.us',   
        'uy'=>'whois.rau.edu.uy',   
        'uz'=>'whois.freenet.uz',   
        've'=>'whois.nic.ve',   
        'wf'=>'whois.nic.fr',   
        'vg'=>'whois.adamsnames.tc',   
        'vi'=>'whois.nic.vi',   
        'vn'=>'whois.batin.com.vn',   
        'vu'=>'whois.vunic.vu',   
        'ws'=>'samoanic.ws',   
        'yt'=>'whois.nic.fr',   
        'yu'=>'whois.nic.yu',   
        'za'=>'whois.co.za',   
        'zm'=>'whois.zamnet.zm'
    );
    // Error: No matching nic server found!
    if (!isset($servers[$ext])) return false;
	
	// encodes
	$encodes = array(
		'kr' => 'euc-kr'
	);
	
	// nic_server
 	if (is_null($nic_server)) {
		$nic_server = $servers[$ext];
		if (in_array($ext, array('com'))) {
			$domain = '='.$domain;
		}
	}

    // connect to whois server:
	set_time_limit(35);
    if ($conn = @fsockopen ($nic_server, 43, $errno, $error, 30)) {
        $output = '';
        fputs($conn, $domain."\r\n");
        while(!feof($conn)) {
            $output .= fgets($conn, 128);
			if(empty($output)) break;
        }
		fclose($conn);

		// detect output
		if ($charset = isset($encodes[$ext]) ? $encodes[$ext] : false){ 
			$output = mb_convert_encoding($output, 'utf-8', $charset);
		}

        return $output;
    }
    // Error: Could not connect to $nic_server!
    return false;
}
?>